package KernelPkg;
import java.util.Arrays;

public class StringClass {

    public void test() {
        /** 字符串和编码 */
        // 在Java中，String是一个引用类型，它本身也是一个class
        String s1 = "Hello!";
        // 字符串在String内部是通过一个char[]数组表示的，因此，按下面的写法也是可以的：
        String s2 = new String(new char[] {'H', 'e', 'l', 'l', 'o', '!'});
        System.out.println(s1);  // Hello!
        System.out.println(s2);  // Hello!

        /** 字符串函数  */
        // equals函数 比较两个字符 区分大小写
        // equalsIgnoreCase 不区分大小写
        System.out.println(s1 == s2);  // false
        System.out.println(s1.equals(s2));  // true

        // contains 是否包含子串
        System.out.println("Hello".contains("ll"));  // true
        System.out.println("Hello".indexOf("l")); // 2 查找某个字段首次出现的索引
        System.out.println("Hello".lastIndexOf("l")); // 3  查找某个字段最后出现的索引
        System.out.println("Hello".startsWith("He")); // true
        System.out.println("Hello".endsWith("lo")); // true

        // substring 根据索引提取子串 含头不含尾
        System.out.println("Hello".substring(2)); // "llo"
        System.out.println("Hello".substring(2, 4)); //  "ll"

        // trim()方法可以移除字符串首尾空白字符。空白字符包括空格，\t，\r，\n
        // strip()方法也可以移除字符串首尾空白字符。它和trim()不同的是，类似中文的空格字符\u3000也会被移除
        System.out.println("  \tHello\r\n ".trim()); // "Hello"

        // isEmpty()判断字符串是否为空
        System.out.println("".isEmpty()); // true，因为字符串长度为0
        System.out.println("  ".isEmpty()); // false，因为字符串长度不为0

        // replace 替换子串  replaceAll使用正则替换
        System.out.println(s1.replace('l', 'w'));  // "hewwo"，所有字符'l'被替换为'w'

        // split分割字符串
        String s3 = "A,B,C,D";
        String[] ss = s3.split("\\,"); // {"A", "B", "C", "D"}
        System.out.println(Arrays.toString(ss));

        // join拼接字符串
        String[] arr = {"A", "B", "C"};
        String s4 = String.join("***", arr); // "A***B***C"

        // 格式化字符串
        // %s：显示字符串；
        // %d：显示整数；
        // %x：显示十六进制整数；
        // %f：显示浮点数。
        String s5 = "Hi %s, your score is %d!";
        System.out.println(String.format(s5, "Bob", 59));

        // valueOf任意基本类型或引用类型转换为字符串
        String.valueOf(123); // "123"
        // 字符串转换为其他类型
        int n1 = Integer.parseInt("123"); // 123
        // 字符串转换为boolean类型
        boolean b1 = Boolean.parseBoolean("true"); // true

        // String和char[]类型可以互相转换
        char[] cs = "Hello".toCharArray(); // String -> char[]
        String s = new String(cs); // char[] -> String

        /** StringBuilder */
        // StringBuilder是一个可变对象，可以预分配缓冲区，这样，往StringBuilder中新增字符时，不会创建新的临时对象
        // StringBuilder是可变对象，用来高效拼接字符串；
        // StringBuilder可以支持链式操作，实现链式操作的关键是返回实例本身；
        // StringBuffer是StringBuilder的线程安全版本，现在很少使用。
        StringBuilder sb = new StringBuilder(1024);  // 指定缓冲区大小 也可以不指定
        sb.setLength(20);    // 限定字符串的长度为20
        sb.append("ssaa");  // 向sb中追加字符  "ssaa"
        sb.reverse();  // 倒序  ”aass“
        sb.setCharAt(0,'帅');    // 在索引值为0的地方改变字符帅 ”帅ass“
        sb.insert(0,'我').insert(1,'爱');  // 在指定位置插入字符  "我爱帅ass"
        int a = sb.indexOf("爱");
        sb.deleteCharAt(0); // 删除指定索引位置的字符
        sb.delete(0,2);     // 删除范围的字符,[0,2),左闭右开
        sb.toString();  // StringBuilder 转 String
        System.out.println(sb);
        System.out.println(a);

        // String 转 StringBuilder
        String s6 = "yes";
        StringBuilder sb6 = new StringBuilder(s6);
        System.out.println(sb6);  // "yes"

        /** 枚举测试 */
        Weekday day = Weekday.SUN;
        System.out.println("Today is " + day.dayValue + ". Work at home!");  // Today is 0. Work at home!
        System.out.println("Today is " + day.name() + ". Work at home!");  // Today is SUN. Work at home!
        System.out.println("Today is " + day.toString() + ". Work at home!");  // Today is 星期日. Work at home!

        // 以数组形式返回枚举类型的所有成员
        for (Weekday weekday : Weekday.values()) {
            System.out.println(weekday.dayValue);
            System.out.println(weekday.name());
            System.out.println(weekday.toString());
        }
        // 将普通字符串转换为枚举实例
        Weekday day2 = Weekday.valueOf("MON");
        System.out.println(day2.toString());  // 星期一

        // 根据值反查返回枚举类型
        Weekday day3 = Weekday.getByValue(3);
        System.out.println(day3.toString());  // 星期三
    }


}

/**
 * 枚举类  
 */
enum Weekday {
    MON(1, "星期一"), TUE(2, "星期二"), WED(3, "星期三"), THU(4, "星期四"), FRI(5, "星期五"), SAT(6, "星期六"), SUN(0, "星期日");

    public final int dayValue;  // 自定义value
    private final String chinese;  // 自定义name

    private Weekday(int dayValue, String chinese) {
        this.dayValue = dayValue;
        this.chinese = chinese;
    }

    @Override
    public String toString() {
        return this.chinese;
    }

    /**
     * 根据dayValue返回合适的枚举类型
     * @param value
     * @return
     */
    public static Weekday getByValue(int value) {
        for (Weekday weekday : values()) {
            if (weekday.dayValue == value) {
                return weekday;
            }
        }
        return null;
    }
}